<template>
  <div class="min-h-screen py-8 px-4 sm:px-6 lg:px-8">
    <div class="max-w-4xl mx-auto">
      <!-- 页面标题 -->
      <div class="text-center mb-12">
        <h1 class="text-4xl font-bold mb-4 tech-text">File System Access API</h1>
        <p class="text-gray-300 text-lg">
          访问本地文件系统，读取和写入文件，创建和管理文件夹
        </p>
      </div>

      <!-- 浏览器支持提示 -->
      <div v-if="!isSupported" class="tech-card mb-8 border-yellow-600">
        <div class="flex items-center mb-4">
          <i class="i-carbon-warning text-yellow-500 text-xl mr-3"></i>
          <h3 class="text-xl font-semibold text-yellow-500">浏览器支持提示</h3>
        </div>
        <p class="text-gray-300 mb-4">
          您的浏览器不支持 File System Access API。此功能需要 Chrome 86+ 或其他支持的浏览器。
        </p>
        <p class="text-gray-400 text-sm">
          注意：此 API 需要用户明确授权才能访问文件系统，并且需要在安全上下文（HTTPS）中使用。
        </p>
      </div>

      <!-- 文件操作 -->
      <div class="tech-card mb-8">
        <h2 class="text-2xl font-semibold mb-6 text-white">文件操作</h2>
        
        <div class="grid grid-cols-1 md:grid-cols-3 gap-6">
          <!-- 选择文件 -->
          <div class="bg-gray-800 rounded-lg p-6">
            <h3 class="text-lg font-semibold text-white mb-4 flex items-center">
              <i class="i-carbon-document text-blue-400 mr-3"></i>
              选择文件
            </h3>
            <p class="text-gray-300 text-sm mb-4">打开并读取本地文件</p>
            <button
              @click="openFile"
              :disabled="!isSupported"
              class="tech-button w-full disabled:opacity-50 disabled:cursor-not-allowed"
            >
              <i class="i-carbon-folder-open mr-2"></i>
              打开文件
            </button>
          </div>

          <!-- 保存文件 -->
          <div class="bg-gray-800 rounded-lg p-6">
            <h3 class="text-lg font-semibold text-white mb-4 flex items-center">
              <i class="i-carbon-save text-green-400 mr-3"></i>
              保存文件
            </h3>
            <p class="text-gray-300 text-sm mb-4">保存内容到本地文件</p>
            <button
              @click="saveFile"
              :disabled="!isSupported || !currentFileContent"
              class="bg-green-600 hover:bg-green-700 disabled:bg-gray-600 disabled:cursor-not-allowed text-white px-4 py-3 rounded-lg transition-colors w-full"
            >
              <i class="i-carbon-save mr-2"></i>
              保存文件
            </button>
          </div>

          <!-- 选择目录 -->
          <div class="bg-gray-800 rounded-lg p-6">
            <h3 class="text-lg font-semibold text-white mb-4 flex items-center">
              <i class="i-carbon-folder text-orange-400 mr-3"></i>
              选择目录
            </h3>
            <p class="text-gray-300 text-sm mb-4">浏览文件夹结构</p>
            <button
              @click="openDirectory"
              :disabled="!isSupported"
              class="bg-orange-600 hover:bg-orange-700 disabled:bg-gray-600 disabled:cursor-not-allowed text-white px-4 py-3 rounded-lg transition-colors w-full"
            >
              <i class="i-carbon-folder-open mr-2"></i>
              打开目录
            </button>
          </div>
        </div>
      </div>

      <!-- 文件编辑器 -->
      <div v-if="currentFile" class="tech-card mb-8">
        <h3 class="text-xl font-semibold mb-6 text-white">文件编辑器</h3>
        
        <div class="space-y-6">
          <!-- 文件信息 -->
          <div class="bg-gray-800 rounded-lg p-4">
            <div class="grid grid-cols-1 md:grid-cols-3 gap-4 text-sm">
              <div>
                <span class="text-gray-400">文件名:</span>
                <span class="text-white ml-2 font-medium">{{ currentFile.name }}</span>
              </div>
              <div>
                <span class="text-gray-400">大小:</span>
                <span class="text-white ml-2">{{ formatFileSize(currentFile.size) }}</span>
              </div>
              <div>
                <span class="text-gray-400">类型:</span>
                <span class="text-white ml-2">{{ currentFile.type || '未知' }}</span>
              </div>
            </div>
          </div>

          <!-- 编辑区域 -->
          <div>
            <div class="flex justify-between items-center mb-3">
              <label class="text-gray-300 font-medium">文件内容:</label>
              <div class="flex gap-2">
                <button
                  @click="saveCurrentFile"
                  :disabled="!hasChanges"
                  class="bg-blue-600 hover:bg-blue-700 disabled:bg-gray-600 disabled:cursor-not-allowed text-white px-3 py-1 rounded text-sm transition-colors"
                >
                  <i class="i-carbon-save mr-1"></i>
                  保存更改
                </button>
                <button
                  @click="reloadFile"
                  class="bg-gray-600 hover:bg-gray-700 text-white px-3 py-1 rounded text-sm transition-colors"
                >
                  <i class="i-carbon-reset mr-1"></i>
                  重新加载
                </button>
              </div>
            </div>
            <textarea
              v-model="currentFileContent"
              rows="15"
              class="w-full bg-gray-800 text-white border border-gray-600 rounded-lg px-4 py-3 font-mono text-sm"
              placeholder="文件内容将显示在这里..."
            ></textarea>
            <div class="flex justify-between items-center mt-2 text-sm">
              <span class="text-gray-400">
                行数: {{ lineCount }} | 字符数: {{ currentFileContent.length }}
              </span>
              <span v-if="hasChanges" class="text-yellow-400">
                <i class="i-carbon-warning-alt mr-1"></i>
                有未保存的更改
              </span>
            </div>
          </div>
        </div>
      </div>

      <!-- 目录浏览器 -->
      <div v-if="currentDirectory" class="tech-card mb-8">
        <h3 class="text-xl font-semibold mb-6 text-white">目录浏览器</h3>
        
        <div class="bg-gray-800 rounded-lg p-4 mb-4">
          <div class="flex items-center justify-between">
            <div class="flex items-center">
              <i class="i-carbon-folder text-orange-400 text-xl mr-3"></i>
              <span class="text-white font-semibold">{{ currentDirectory.name }}</span>
            </div>
            <button
              @click="refreshDirectory"
              class="bg-blue-600 hover:bg-blue-700 text-white px-3 py-1 rounded text-sm transition-colors"
            >
              <i class="i-carbon-renew mr-1"></i>
              刷新
            </button>
          </div>
        </div>

        <!-- 文件列表 -->
        <div v-if="directoryEntries.length > 0" class="space-y-2 max-h-96 overflow-y-auto">
          <div
            v-for="(entry, index) in directoryEntries"
            :key="index"
            class="bg-gray-800 rounded-lg p-4 hover:bg-gray-750 transition-colors cursor-pointer"
            @click="handleEntryClick(entry)"
          >
            <div class="flex items-center justify-between">
              <div class="flex items-center flex-1">
                <i 
                  :class="entry.kind === 'directory' ? 'i-carbon-folder text-orange-400' : 'i-carbon-document text-blue-400'"
                  class="text-xl mr-3"
                ></i>
                <div class="flex-1">
                  <div class="text-white font-medium">{{ entry.name }}</div>
                  <div class="text-gray-400 text-xs">
                    {{ entry.kind === 'directory' ? '文件夹' : '文件' }}
                  </div>
                </div>
              </div>
              <div class="flex gap-2">
                <button
                  v-if="entry.kind === 'file'"
                  @click.stop="readDirectoryFile(entry)"
                  class="bg-blue-600 hover:bg-blue-700 text-white px-3 py-1 rounded text-sm transition-colors"
                >
                  <i class="i-carbon-view mr-1"></i>
                  查看
                </button>
              </div>
            </div>
          </div>
        </div>

        <div v-else-if="isLoadingDirectory" class="text-center py-8">
          <i class="i-carbon-loading text-4xl mb-4 block mx-auto animate-spin text-tech-accent"></i>
          <p class="text-gray-300">正在加载目录...</p>
        </div>

        <div v-else class="text-center py-8 text-gray-400">
          <i class="i-carbon-folder-off text-4xl mb-4 block mx-auto opacity-50"></i>
          <p>目录为空或没有权限访问</p>
        </div>
      </div>

      <!-- 快捷操作 -->
      <div class="tech-card mb-8">
        <h3 class="text-xl font-semibold mb-6 text-white">快捷操作</h3>
        
        <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
          <button
            @click="createNewFile"
            :disabled="!isSupported"
            class="bg-green-600 hover:bg-green-700 disabled:bg-gray-600 disabled:cursor-not-allowed text-white px-4 py-3 rounded-lg transition-colors"
          >
            <i class="i-carbon-document-add mr-2"></i>
            创建新文件
          </button>
          
          <button
            @click="openTextFile"
            :disabled="!isSupported"
            class="bg-blue-600 hover:bg-blue-700 disabled:bg-gray-600 disabled:cursor-not-allowed text-white px-4 py-3 rounded-lg transition-colors"
          >
            <i class="i-carbon-text-creation mr-2"></i>
            打开文本文件
          </button>
          
          <button
            @click="openImageFile"
            :disabled="!isSupported"
            class="bg-purple-600 hover:bg-purple-700 disabled:bg-gray-600 disabled:cursor-not-allowed text-white px-4 py-3 rounded-lg transition-colors"
          >
            <i class="i-carbon-image mr-2"></i>
            打开图片文件
          </button>
          
          <button
            @click="exportData"
            :disabled="!isSupported"
            class="bg-orange-600 hover:bg-orange-700 disabled:bg-gray-600 disabled:cursor-not-allowed text-white px-4 py-3 rounded-lg transition-colors"
          >
            <i class="i-carbon-export mr-2"></i>
            导出数据
          </button>
        </div>
      </div>

      <!-- 操作历史 -->
      <div v-if="operationHistory.length > 0" class="tech-card mb-8">
        <h3 class="text-xl font-semibold mb-4 text-white">操作历史</h3>
        
        <div class="space-y-3 max-h-64 overflow-y-auto">
          <div
            v-for="(record, index) in operationHistory.slice().reverse()"
            :key="index"
            class="bg-gray-800 rounded-lg p-4"
          >
            <div class="flex justify-between items-start">
              <div class="flex-1">
                <div class="flex items-center gap-3 mb-2">
                  <span :class="record.success ? 'text-green-400' : 'text-red-400'" class="text-sm font-semibold">
                    {{ record.success ? '✓ 成功' : '✗ 失败' }}
                  </span>
                  <span class="text-white font-medium">{{ record.operation }}</span>
                </div>
                <p class="text-gray-300 text-sm">{{ record.details }}</p>
              </div>
              <span class="text-gray-400 text-sm">{{ formatTimestamp(record.timestamp) }}</span>
            </div>
          </div>
        </div>
        
        <div class="mt-4 pt-4 border-t border-gray-700">
          <button
            @click="clearHistory"
            class="bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded-lg transition-colors text-sm"
          >
            <i class="i-carbon-trash-can mr-1"></i>
            清空历史
          </button>
        </div>
      </div>

      <!-- 错误信息 -->
      <div v-if="error" class="tech-card border-red-600 mb-8">
        <div class="flex items-center mb-2">
          <i class="i-carbon-warning text-red-500 text-xl mr-3"></i>
          <h3 class="text-xl font-semibold text-red-500">错误</h3>
        </div>
        <p class="text-gray-300">{{ error }}</p>
      </div>

      <!-- API 信息 -->
      <div class="tech-card">
        <h3 class="text-xl font-semibold mb-4 text-white">API 信息</h3>
        <div class="space-y-4 text-gray-300">
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">浏览器支持</h4>
            <p>Chrome 86+, Edge 86+ (需要启用实验性功能)</p>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">主要方法</h4>
            <ul class="list-disc list-inside space-y-1">
              <li><code class="bg-gray-800 px-2 py-1 rounded">window.showOpenFilePicker()</code> - 选择文件</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">window.showSaveFilePicker()</code> - 保存文件</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">window.showDirectoryPicker()</code> - 选择目录</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">fileHandle.getFile()</code> - 读取文件</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">fileHandle.createWritable()</code> - 写入文件</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">使用场景</h4>
            <ul class="list-disc list-inside space-y-1">
              <li>文本编辑器和IDE</li>
              <li>图片和视频编辑应用</li>
              <li>文档管理系统</li>
              <li>代码编辑和开发工具</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">权限和安全</h4>
            <ul class="list-disc list-inside space-y-1">
              <li>需要用户明确选择文件或目录</li>
              <li>每次访问都需要用户授权</li>
              <li>必须在安全上下文（HTTPS）中使用</li>
              <li>无法访问系统敏感目录</li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'

// 类型定义
interface OperationRecord {
  operation: string
  details: string
  success: boolean
  timestamp: number
}

interface DirectoryEntry {
  name: string
  kind: 'file' | 'directory'
  handle: any
}

// 响应式状态
const isSupported = ref(false)
const currentFile = ref<File | null>(null)
const currentFileHandle = ref<any>(null)
const currentFileContent = ref('')
const originalFileContent = ref('')
const currentDirectory = ref<any>(null)
const directoryEntries = ref<DirectoryEntry[]>([])
const isLoadingDirectory = ref(false)
const operationHistory = ref<OperationRecord[]>([])
const error = ref('')

// 计算属性
const hasChanges = computed(() => currentFileContent.value !== originalFileContent.value)

const lineCount = computed(() => currentFileContent.value.split('\n').length)

// 检查浏览器支持
isSupported.value = 'showOpenFilePicker' in window

// 打开文件
const openFile = async () => {
  try {
    error.value = ''
    
    const [fileHandle] = await (window as any).showOpenFilePicker({
      types: [
        {
          description: '所有文件',
          accept: { '*/*': [] }
        }
      ],
      multiple: false
    })
    
    currentFileHandle.value = fileHandle
    await readFileContent(fileHandle)
    
    addToHistory('打开文件', `成功打开文件: ${fileHandle.name}`, true)
  } catch (err: any) {
    if (err.name !== 'AbortError') {
      console.error('打开文件失败:', err)
      error.value = err.message || '打开文件失败'
      addToHistory('打开文件', '用户取消或发生错误', false)
    }
  }
}

// 读取文件内容
const readFileContent = async (fileHandle: any) => {
  try {
    const file = await fileHandle.getFile()
    currentFile.value = file
    
    const text = await file.text()
    currentFileContent.value = text
    originalFileContent.value = text
  } catch (err) {
    console.error('读取文件失败:', err)
    error.value = err instanceof Error ? err.message : '读取文件失败'
  }
}

// 保存文件
const saveFile = async () => {
  try {
    error.value = ''
    
    const fileHandle = await (window as any).showSaveFilePicker({
      suggestedName: currentFile.value?.name || 'untitled.txt',
      types: [
        {
          description: '文本文件',
          accept: { 'text/plain': ['.txt'] }
        }
      ]
    })
    
    const writable = await fileHandle.createWritable()
    await writable.write(currentFileContent.value)
    await writable.close()
    
    currentFileHandle.value = fileHandle
    originalFileContent.value = currentFileContent.value
    
    addToHistory('保存文件', `成功保存文件: ${fileHandle.name}`, true)
  } catch (err: any) {
    if (err.name !== 'AbortError') {
      console.error('保存文件失败:', err)
      error.value = err.message || '保存文件失败'
      addToHistory('保存文件', '保存失败', false)
    }
  }
}

// 保存当前文件
const saveCurrentFile = async () => {
  if (!currentFileHandle.value) {
    await saveFile()
    return
  }
  
  try {
    error.value = ''
    
    const writable = await currentFileHandle.value.createWritable()
    await writable.write(currentFileContent.value)
    await writable.close()
    
    originalFileContent.value = currentFileContent.value
    
    addToHistory('保存更改', `成功保存到: ${currentFileHandle.value.name}`, true)
  } catch (err) {
    console.error('保存更改失败:', err)
    error.value = err instanceof Error ? err.message : '保存更改失败'
    addToHistory('保存更改', '保存失败', false)
  }
}

// 重新加载文件
const reloadFile = async () => {
  if (currentFileHandle.value) {
    await readFileContent(currentFileHandle.value)
    addToHistory('重新加载', `重新加载文件: ${currentFileHandle.value.name}`, true)
  }
}

// 打开目录
const openDirectory = async () => {
  try {
    error.value = ''
    isLoadingDirectory.value = true
    
    const dirHandle = await (window as any).showDirectoryPicker()
    currentDirectory.value = dirHandle
    
    await loadDirectoryEntries(dirHandle)
    
    addToHistory('打开目录', `成功打开目录: ${dirHandle.name}`, true)
  } catch (err: any) {
    if (err.name !== 'AbortError') {
      console.error('打开目录失败:', err)
      error.value = err.message || '打开目录失败'
      addToHistory('打开目录', '打开失败', false)
    }
  } finally {
    isLoadingDirectory.value = false
  }
}

// 加载目录条目
const loadDirectoryEntries = async (dirHandle: any) => {
  directoryEntries.value = []
  
  for await (const entry of dirHandle.values()) {
    directoryEntries.value.push({
      name: entry.name,
      kind: entry.kind,
      handle: entry
    })
  }
  
  // 排序：文件夹在前，文件在后
  directoryEntries.value.sort((a, b) => {
    if (a.kind === b.kind) {
      return a.name.localeCompare(b.name)
    }
    return a.kind === 'directory' ? -1 : 1
  })
}

// 刷新目录
const refreshDirectory = async () => {
  if (currentDirectory.value) {
    isLoadingDirectory.value = true
    await loadDirectoryEntries(currentDirectory.value)
    isLoadingDirectory.value = false
    addToHistory('刷新目录', `刷新: ${currentDirectory.value.name}`, true)
  }
}

// 处理条目点击
const handleEntryClick = async (entry: DirectoryEntry) => {
  if (entry.kind === 'file') {
    await readDirectoryFile(entry)
  } else {
    // 可以扩展为进入子目录
    addToHistory('点击文件夹', `点击了文件夹: ${entry.name}`, true)
  }
}

// 读取目录中的文件
const readDirectoryFile = async (entry: DirectoryEntry) => {
  try {
    currentFileHandle.value = entry.handle
    await readFileContent(entry.handle)
    addToHistory('读取文件', `读取: ${entry.name}`, true)
  } catch (err) {
    console.error('读取文件失败:', err)
    error.value = err instanceof Error ? err.message : '读取文件失败'
    addToHistory('读取文件', `读取失败: ${entry.name}`, false)
  }
}

// 创建新文件
const createNewFile = () => {
  currentFile.value = new File([''], 'untitled.txt', { type: 'text/plain' })
  currentFileHandle.value = null
  currentFileContent.value = '# 新建文件\n\n在这里开始编辑...\n'
  originalFileContent.value = ''
  addToHistory('创建新文件', '创建了一个新的空白文件', true)
}

// 打开文本文件
const openTextFile = async () => {
  try {
    const [fileHandle] = await (window as any).showOpenFilePicker({
      types: [
        {
          description: '文本文件',
          accept: {
            'text/plain': ['.txt'],
            'text/markdown': ['.md'],
            'text/javascript': ['.js'],
            'text/typescript': ['.ts']
          }
        }
      ]
    })
    
    currentFileHandle.value = fileHandle
    await readFileContent(fileHandle)
    addToHistory('打开文本文件', `打开: ${fileHandle.name}`, true)
  } catch (err: any) {
    if (err.name !== 'AbortError') {
      error.value = err.message || '打开文本文件失败'
    }
  }
}

// 打开图片文件
const openImageFile = async () => {
  try {
    const [fileHandle] = await (window as any).showOpenFilePicker({
      types: [
        {
          description: '图片文件',
          accept: {
            'image/*': ['.png', '.jpg', '.jpeg', '.gif', '.webp']
          }
        }
      ]
    })
    
    const file = await fileHandle.getFile()
    currentFile.value = file
    currentFileContent.value = `[图片文件: ${file.name}]\n\n大小: ${formatFileSize(file.size)}\n类型: ${file.type}`
    
    addToHistory('打开图片', `打开图片: ${fileHandle.name}`, true)
  } catch (err: any) {
    if (err.name !== 'AbortError') {
      error.value = err.message || '打开图片文件失败'
    }
  }
}

// 导出数据
const exportData = async () => {
  try {
    const data = {
      operations: operationHistory.value,
      timestamp: new Date().toISOString(),
      currentFile: currentFile.value?.name
    }
    
    const fileHandle = await (window as any).showSaveFilePicker({
      suggestedName: 'export.json',
      types: [
        {
          description: 'JSON 文件',
          accept: { 'application/json': ['.json'] }
        }
      ]
    })
    
    const writable = await fileHandle.createWritable()
    await writable.write(JSON.stringify(data, null, 2))
    await writable.close()
    
    addToHistory('导出数据', '成功导出操作历史', true)
  } catch (err: any) {
    if (err.name !== 'AbortError') {
      error.value = err.message || '导出数据失败'
      addToHistory('导出数据', '导出失败', false)
    }
  }
}

// 添加到历史记录
const addToHistory = (operation: string, details: string, success: boolean) => {
  operationHistory.value.push({
    operation,
    details,
    success,
    timestamp: Date.now()
  })
  
  // 只保留最近50条记录
  if (operationHistory.value.length > 50) {
    operationHistory.value.splice(0, operationHistory.value.length - 50)
  }
}

// 清空历史记录
const clearHistory = () => {
  operationHistory.value = []
}

// 格式化文件大小
const formatFileSize = (bytes: number): string => {
  if (bytes === 0) return '0 Bytes'
  const k = 1024
  const sizes = ['Bytes', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

// 格式化时间戳
const formatTimestamp = (timestamp: number): string => {
  return new Date(timestamp).toLocaleTimeString('zh-CN')
}
</script>
